#include "List.h"
#include "Circle.h"
#include "Rect.h"

// ���������� ������ m_Data ������ ����� ������ �������, �� ������� ��������� pc 
Node::Node(Node* Prev, const Shape& pc) :m_Data(pc.CopyObj())
{
	//�������� ���� ����()����������� � ���� � ����
	
	pPrev = Prev;
	pNext = Prev->pNext;

	Prev->pNext = this;
	pNext->pPrev = this;
}

Node::~Node()
{
	if (pPrev) { pPrev->pNext = /*this->*/pNext; }
	if (pNext) { pNext->pPrev = /*this->*/pPrev; }

	pPrev = pNext = nullptr;
	delete m_Data;
}

void Node::Copy_Data(const Node& other)	try 
{
	*this->m_Data = *other.m_Data;
}
catch (const std::bad_cast&) 
{
	delete this->m_Data;
	this->m_Data = other.m_Data->CopyObj();
}
catch (...) { std::cout << "unknown err" << std::endl;/*abort;*/ }


double Node::Get_Meth(Sorting to)const
{
	double res;

	switch (to)
	{
	case to_area: {res = m_Data->Get_area(); }
				break;
	case to_colour: {res = m_Data->Get_colour(); }
				  break;
	case to_distance: {res = m_Data->Get_distance(); }
					break;
	default:	break;
	}

	return res;
}

std::ostream& operator<<(std::ostream& os, const Node& node)
{
	const char* type = typeid(*(node.m_Data)).name();
	int i_switch = 0;

	if (type == typeid(Rect).name())
	{
		i_switch = 1;
	}

	if (type == typeid(Circle).name())
	{
		i_switch = 2;
	}

	switch (i_switch)
	{
	case 1: {os << "Rect: " << dynamic_cast<Rect&>(*(node.m_Data)); break; }
	case 2: {os << "Circle: " << dynamic_cast<Circle&>(*(node.m_Data)); break; }
	default: os << "err";
	}

	return os;
}